<template>
  <div class="icon-cropper-wrap">
    <el-dialog
      v-if="isVisible"
      v-model="isVisible"
      :title="$demoi18n('label.iconCropperDialog.dialogTitle')"
      :close-on-click-modal="false"
      :append-to-body="true"
      :destroy-on-close="true"
      width="900px"
      :class="`${visualThemeClassName} ${xvueNameSpace}`"
      @close="cancel"
    >
      <div class="icon-cropper">
        <div class="left_content">
          <div class="topBtn">
            <el-button
              v-show="!isUseCrop"
              size="default"
              type="primary"
              @click="useCrop()"
            >{{
              $demoi18n('label.iconCropperDialog.useCrop')
            }}</el-button>
            <el-button
              v-show="isUseCrop"
              size="default"
              type="primary"
              @click="userOrgImg()"
            >{{
              $demoi18n('label.iconCropperDialog.useOriginalImage')
            }}</el-button>
          </div>
          <div class="explain-text">{{ $demoi18n('label.iconCropperDialog.originalImage') }}</div>
          <div class="org_img">
            <img
              ref="orgImg"
              :src="orgImgUrl_"
              @load="initCropper"
            />
          </div>
          <div
            v-show="isUseCrop"
            class="actions"
          >
            <el-button-group>
              <el-button
                type="primary"
                size="default"
                icon="RefreshLeft"
                @click="handleRotate(-90)"
              ></el-button>
              <el-button
                type="primary"
                size="default"
                icon="RefreshRight"
                @click="handleRotate(90)"
              ></el-button>
            </el-button-group>
            <el-button-group>
              <el-button
                type="primary"
                size="default"
                @click="setAspectRatio(16 / 9)"
              >16:9</el-button>
              <el-button
                type="primary"
                size="default"
                @click="setAspectRatio(4 / 3)"
              >4:3</el-button>
              <el-button
                type="primary"
                size="default"
                @click="setAspectRatio(1 / 1)"
              >1:1</el-button>
              <el-button
                type="primary"
                size="default"
                @click="setAspectRatio(2 / 3)"
              >2:3</el-button>
              <el-button
                type="primary"
                size="default"
                @click="setAspectRatio(NaN)"
              >free</el-button>
            </el-button-group>
          </div>
        </div>
        <div class="right_content">
          <div class="explain-text">{{ $demoi18n('label.iconCropperDialog.crop') }}</div>
          <div class="preview_img">
            <img :src="cropImg" />
          </div>
          <div
            v-if="isUseCrop"
            class="info"
          >
            <div><span class="label">X:</span><span class="value">{{ cropX }}</span></div>
            <div><span class="label">Y:</span><span class="value">{{ cropY }}</span></div>
            <div><span class="label">W:</span><span class="value">{{ cropWidth }}</span></div>
            <div><span class="label">H:</span><span class="value">{{ cropHeight }}</span></div>
          </div>
        </div>
      </div>
      <template #footer>
        <span>
          <el-button
            class="button-cancel"
            size="default"
            @click="cancel()"
          >{{ $demoi18n('btn.cancel') }}</el-button>
          <el-button
            class="btn-sure"
            size="default"
            type="primary"
            @click="confirm()"
          >{{ $demoi18n('btn.confirm') }}</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import IconUploadMixin from '@/components/common/icon/icon-upload-mixin.js';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.min.css';
import demoImg from '../../../../AssetPack/web/web-components/overview-images/visual_components_basic_pie.png';
import { nextTick } from 'vue';

export default {
  components: {},
  mixins: [IconUploadMixin],
  props: {
    icon: Object,
    orgImgUrl: {
      type: String,
      default: demoImg,
    },
    visible: {
      type: Boolean,
      default: false,
    },
    cateId: {
      type: String,
      default: '',
    },
  },
  emits: ['confirm', 'cancel'],
  data() {
    return {
      xvueNameSpace: process.env.xvueNameSpace, // 给挂载在body下的元素加上主类名
      cropper: null,
      options: {
        aspectRatio: NaN,
        checkCrossOrigin: true,
        viewMode: 2,
        rotatable: true,
        autoCropArea: 0.8,
      },
      cropImg: '',
      isUseCrop: true,
      isVisible: false,
      orgImgUrl_: '',
      cropTimer: null,
      cropX: 0,
      cropY: 0,
      cropWidth: 0,
      cropHeight: 0,
    };
  },
  computed: {
  },
  watch: {
    visible: {
      handler(val) {
        this.isVisible = val;
      },
      immediate: true,
    },
    orgImgUrl: {
      handler(imgUrl) {
        this.orgImgUrl_ = imgUrl;
      },
      immediate: true,
    },
  },
  beforeUnmount() {
    window.URL.revokeObjectURL(this.cropImg);
  },
  methods: {
    initCropper() {
      if (this.cropper) {
        this.cropper.destroy();
        this.cropper = null;
      }
      this.cropper = new Cropper(this.$refs.orgImg, {
        ...this.options,
        crop: this.sureCropper,
      });
    },

    sureCropper(e) {
      const { width, height, x, y } = e.detail;
      this.cropX = Math.floor(x);
      this.cropY = Math.floor(y);
      this.cropWidth = Math.floor(width);
      this.cropHeight = Math.floor(height);

      clearTimeout(this.cropTimer);
      this.cropTimer = setTimeout(() => {
        this.cropper.getCroppedCanvas().toBlob(blob => {
          window.URL.revokeObjectURL(this.cropImg);
          this.cropImg = window.URL.createObjectURL(blob);
        }, 'image/png');
      }, 50);
    },
    handleRotate(deg) {
      this.cropper.rotate(deg);
      this.cropper.clear();
      nextTick(() => {
        this.cropper.crop();
      });
    },
    setOption(key, value) {
      this.options[key] = value;
      this.initCropper();
    },
    setAspectRatio(radio) {
      this.cropper.setAspectRatio(radio);
    },
    useCrop() {
      this.initCropper();
      this.isUseCrop = true;
    },
    userOrgImg() {
      this.cropper.destroy();
      this.cropper = null;
      this.cropImg = this.orgImgUrl;
      this.isUseCrop = false;
    },
    cancel() {
      this.$emit('cancel');
    },
    confirm() {
      this.saveCropperImage();
    },
    saveCropperImage() {
      if (!this.isUseCrop) {
        const res = {
          action: 'crop',
          isSuccess: false,
          isUseCrop: false,
        };
        this.$emit('confirm', res);
        return;
      }
      this.cropper.getCroppedCanvas().toBlob(blob => {
        let { cateId } = this;
        if (cateId === 'custom') {
          cateId = '';
        }

        this.uploadImageData({ file: blob, type: 6, cateId }).then(res => {
          res.action = 'crop',
          res.isUseCrop = true;
          this.$emit('confirm', res);
        });
      });
    },
  },
};
</script>
<style lang="less" scoped>
.icon-cropper {
  width: 800px;
  display: flex;
  justify-content: space-between;
  .left_content {
    position: relative;
    width: 500px;
    .topBtn {
      position: absolute;
      top: 30px;
      right: 10px;
      z-index: 1;
    }
    .org_img {
      max-height: 400px;
      overflow: hidden;
      img {
        max-width: 100%;
        max-height: 100%;
      }
    }
    .actions {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-top: 10px;
      .el-button-group {
        margin: 0 5px;
      }
    }
  }
  .right_content {
    width: 280px;
    .preview_img {
      width: 100%;
      height: 280px;
      border: 1px solid #999;
      img {
        max-width: 100%;
        max-height: 100%;
      }
    }
    .info {
      margin-top: 10px;
      div {
        display: flex;
        .label {
          width: 20px;
          text-align: center;
          margin-right: 10px;
          color: #607d8b;
        }
      }
    }
  }
}
</style>
